home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJEMU106.ARJ / E16.CC < prev    next >
C/C++ Source or Header  |  1992-03-02  |  4KB  |  220 lines

  1. #include "emu.h"
  2. #include "rmov.h"
  3. #include "const.h"
  4. #include "compare.h"
  5.  
  6. void f2xm1()
  7. {
  8.   if (empty())
  9.     return;
  10.   reg xloga, val, rv, bottom, tmp;
  11.   long i;
  12.  
  13.   r_mul(CONST_LN2, st(), xloga);
  14.   r_mov(xloga, val);
  15.   r_mov(xloga, rv);
  16.  
  17.   for (i=2; i<16; i++)
  18.   {
  19.     r_mov(&i, bottom);
  20.     r_mul(val, xloga, tmp);
  21.     r_div(tmp, bottom, val);
  22.     r_add(val, rv, tmp);
  23.     r_mov(tmp, rv);
  24.   }
  25.   r_mov(rv, st());
  26. }
  27.  
  28. // logb(x) = loga(x) / loga(b)
  29. // log2(x) = loge(x) / loge(2)
  30.  
  31. void fyl2x()
  32. {
  33.   if (empty())
  34.     return;
  35.   reg z, x, nom, denom, xsquare, term, temp, sum, pow;
  36.   long exponent;
  37.   reg CONST_SQRT2 = { SIGN_POS, TW_V, EXP_BIAS, 0xf9de6000, 0xb504f333 };
  38.  
  39.   r_mov(st(), z);
  40.   if ((z.tag != TW_V) || (z.sign != SIGN_POS)) {
  41.     return exception(EX_I); // not valid, zero or negative
  42.   }  
  43.   exponent = (long)(z.exp - EXP_BIAS);
  44.   z.exp=EXP_BIAS;
  45.   if (compare(z, CONST_SQRT2) == COMP_A_GT_B) {
  46.     (z.exp)--;
  47.     exponent++;
  48.   }
  49.  
  50.   r_sub(z, CONST_1, nom);
  51.   r_add(z, CONST_1, denom);
  52.   r_div(nom, denom, x);
  53.   r_mov(x, pow);
  54.   r_mov(x, sum);
  55.   r_mul(x, x, xsquare);
  56.   
  57.   for (long i=3; i<25; i+=2)
  58.   {
  59.     r_mul(pow, xsquare, temp);
  60.     r_mov(temp, pow);
  61.  
  62.     r_mov(&i, denom);
  63.     r_div(pow, denom, term);
  64.  
  65.     r_add(term, sum, temp);
  66.     r_mov(temp, sum);
  67.   }
  68.   r_div(sum, CONST_LN2, temp);
  69.   temp.exp++;
  70.   if (exponent) {
  71.     r_mov(&exponent, term);
  72.     r_add(term, temp, sum);
  73.   } else {
  74.     r_mov(temp, sum);
  75.   }
  76.  
  77.   r_mul(sum, st(1), temp);
  78.   r_mov(temp, st(1));
  79.   st().tag = TW_E;
  80.   top++;
  81. }
  82.  
  83. void fptan()
  84. {
  85.   extern void fsincos();
  86.   fsincos();
  87.   if (empty(1))
  88.     return;
  89.   reg tmp;
  90.   r_div(st(1), st(), tmp);
  91.   r_mov(tmp, st(1));
  92.   r_mov(CONST_1, st());
  93. }
  94.  
  95. void fpatan()
  96. {
  97.   if (empty(1))
  98.     return;
  99.   if (mag_same(st(), CONST_Z))
  100.   {
  101.     r_mov(CONST_PI2, st(1));
  102.     st().tag = TW_E;
  103.     top++;
  104.     return;
  105.   }
  106.   if (mag_same(st(1), CONST_Z))
  107.   {
  108.     r_mov(CONST_Z, st(1));
  109.     st().tag = TW_E;
  110.     top++;
  111.     return;
  112.   }
  113.   reg x2, sum, term, pow, temp;
  114.   int quadrant = 0;
  115.   if (st(1).sign == SIGN_NEG)
  116.     quadrant |= 1;
  117.   if (st(0).sign == SIGN_NEG)
  118.     quadrant |= 2;
  119.   st(1).sign = st().sign = SIGN_POS;
  120.   if (compare(st(1), st()) == COMP_A_GT_B)
  121.   {
  122.     quadrant |= 4;
  123.     r_mov(st(1), temp);
  124.     r_mov(st(), st(1));
  125.     r_mov(temp, st());
  126.   }
  127.  
  128.   r_div(st(1), st(), sum);
  129.   r_mul(sum, sum, x2);
  130.   r_mov(sum, pow);
  131.  
  132.   x2.sign ^= SIGN_POS^SIGN_NEG;
  133.  
  134.   for (long i=3; i<25; i+=2)
  135.   {
  136.     r_mul(pow, x2, temp);
  137.     r_mov(temp, pow);
  138.     r_mov(&i, temp);
  139.     r_div(pow, temp, term);
  140.     r_add(sum, term, temp);
  141.     r_mov(temp, sum);
  142.   }
  143.  
  144.   if (quadrant & 4)
  145.   {
  146.     r_sub(CONST_PI2, sum, temp);
  147.     r_mov(temp, sum);
  148.   }
  149.   if (quadrant & 2)
  150.   {
  151.     r_sub(CONST_PI, sum, temp);
  152.     r_mov(temp, sum);
  153.   }
  154.   if (quadrant & 1)
  155.     sum.sign ^= SIGN_POS^SIGN_NEG;
  156.  
  157.   r_mov(sum, st(1));
  158.   st().tag = TW_E;
  159.   top++;
  160. }
  161.  
  162. void fxtract()
  163. {
  164.   if (empty())
  165.     return;
  166.   if (full())
  167.     return;
  168.   top--;
  169.   r_mov(st(1), st());
  170.   st().exp = EXP_BIAS;
  171.   long e = st(1).exp - EXP_BIAS;
  172.   r_mov(&e, st(1));
  173. }
  174.  
  175. extern int fprem_do(reg&,reg&,int);
  176.  
  177. void fprem1()
  178. {
  179.   if (empty(1))
  180.     return;
  181.   int q = fprem_do(st(), st(1), RC_RND);
  182.   if (q == -1)
  183.     setcc(SW_C2);
  184.   else
  185.   {
  186.     int c = 0;
  187.     if (q&4) c |= SW_C3;
  188.     if (q&2) c |= SW_C1;
  189.     if (q&1) c |= SW_C0;
  190.     setcc(c);
  191.   }
  192. }
  193.  
  194. void fdecstp()
  195. {
  196.   top--;
  197. }
  198.  
  199. void fincstp()
  200. {
  201.   top++;
  202. }
  203.  
  204. FUNC emu_16_table[] = {
  205.   f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp
  206. };
  207.  
  208. void emu_16()
  209. {
  210.   if (modrm > 0277)
  211.   {
  212.     (emu_16_table[modrm&7])();
  213.   }
  214.   else
  215.   {
  216.     emu_bad();
  217.   }
  218. }
  219.  
  220.